module fsk_dem (
    input wire clk,
    input wire rst_n,
    input wire signed [11: 0] in,
    input wire in_valid,
    output reg dout,
    output reg write
);

    localparam SAMPLE_RATE = 10e6;
    localparam SAMPLE_PER_SYMBOL = 100;
    localparam PASS_ZERO_THRESHOLD = 4;
    localparam HIGH_LIM = 100;
    localparam LOW_LIM = -100;

    reg [7: 0] cnt;
    reg last_level;
    reg demod;
    wire detect = last_level ? (in < LOW_LIM) : (in > HIGH_LIM);
    // reg trig;

    always @(posedge clk) begin
        if (~rst_n) begin
            cnt <= 0; 
            last_level <= 0;
            demod <= 0;
        end else begin
            last_level <= in > 0;
            if (detect) begin
                cnt <= 0;
                if (cnt > PASS_ZERO_THRESHOLD) begin
                    demod <= 1; 
                end else begin
                    demod <= 0; 
                end
            end else begin
                cnt <= cnt + 1;
                demod <= demod; 
            end
        end
    end

    localparam PHASE_INC = 17'h10000 / SAMPLE_PER_SYMBOL;
    reg [16:0] phase;
    reg [16:0] phase_to_inc;
    reg [1:0] demod_buff;
    always @(posedge clk) begin : proc_sync
        if(~rst_n) begin
            demod_buff <= 0;
            phase <= 17'h0000;
            // trig <= 0;
        end else begin
            // if (in != 0)
            //     trig <= 1;

            if(in_valid) begin
                demod_buff <= {demod_buff[0], demod};
                phase_to_inc = PHASE_INC;
                // 如果 demod 发生变化（上升沿/下降沿），如果此时相位恰好为 1/2
                // 最大相位（0x8000），则说明当前抽样位置在正中间。若不是则说明
                // 当前抽样位置有所偏移，应该通过额外的相位累加以进行调整
                if (demod_buff[1] ^ demod_buff[0]) begin
                    if (phase < (17'h8000 - (PHASE_INC >> 1))) begin
                        phase_to_inc = phase_to_inc + (PHASE_INC >> 1);
                    end else begin
                        phase_to_inc = phase_to_inc - (PHASE_INC >> 1);
                    end
                end
                // 相位累加器发生溢出时即抽样时刻
                if (phase + phase_to_inc > 17'h10000) begin
                    phase <= (phase + phase_to_inc) & 17'hffff;
                    // 输出 write 脉冲，赋值 dout
                    // if (trig)
                    write <= 1;
                    dout <= demod;
                end else begin
                    phase <= (phase + phase_to_inc);
                    write <= 0;
                end
            end
        end
    end

    
endmodule